package cn.bby.tools.dialog;

import cn.bby.tools.actions.GenTemplateAction;
import cn.bby.tools.utils.MessageUtil;
import cn.bby.tools.utils.UserUtil;
import com.intellij.ide.util.PackageChooserDialog;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiPackage;
import com.intellij.util.ui.JBUI;
import com.intellij.util.xmlb.XmlSerializerUtil;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.util.HashSet;
import java.util.Set;

/**
 * @author ben
 * @since 2025/9/24 22:05
 */ // 自定义对话框
public class TemplateGenInputDialog extends DialogWrapper {
    private final Project project;
    private final GenTemplateAction.GenTemplateState state;
    private JTextField projectDirField;
    private JTextField packageField;
    private JTextField templateField;
    Set<String> selectedFiles = new HashSet<>();
    private JTextField userField;
    private JCheckBox overwriteCheck;
    private JTextArea noteArea;
    private JPanel checkBoxPanel;

    public TemplateGenInputDialog(@Nullable Project project, GenTemplateAction.GenTemplateState state) {
        super(project);
        this.project = project;
        this.state = state;
        setTitle(MessageUtil.getMessage("action.BBY.GenTemplateAction.text"));
        init();
    }

    @Override
    protected @Nullable JComponent createCenterPanel() {
        JPanel panel = new JPanel(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = JBUI.insets(5);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 项目目录选择
        gbc.gridx = 0;
        gbc.gridy = 0;
        panel.add(new JLabel(MessageUtil.getMessageSuffix("message.ProjectDir")), gbc);
        gbc.gridx = 1;
        projectDirField = new JTextField(30);
        projectDirField.setText(state.projectDir);
        panel.add(projectDirField, gbc);
        gbc.gridx = 2;
        JButton browseBtn = new JButton(MessageUtil.getMessage("message.Browse"));
        browseBtn.addActionListener(e -> {
            VirtualFile dir = FileChooser.chooseFile(
                    FileChooserDescriptorFactory.createSingleFolderDescriptor(),
                    project, null);
            if (dir != null) {
                projectDirField.setText(dir.getPath());
            }
        });
        panel.add(browseBtn, gbc);

        // 包名选择
        gbc.gridx = 0;
        gbc.gridy = 1;
        panel.add(new JLabel(MessageUtil.getMessageSuffix("message.TargetPackage")), gbc);
        gbc.gridx = 1;
        packageField = new JTextField(30);
        packageField.setText(state.savePkg);
        panel.add(packageField, gbc);
        gbc.gridx = 2;
        JButton packageBtn = new JButton(MessageUtil.getMessage("message.SelectPackage"));
        packageBtn.addActionListener(e -> {
            PackageChooserDialog chooser = new PackageChooserDialog("选择包", project);
            chooser.show();
            PsiPackage selectedPackage = chooser.getSelectedPackage();
            if (selectedPackage != null && StringUtils.isNoneBlank(selectedPackage.getQualifiedName())) {
                packageField.setText(selectedPackage.getQualifiedName());
            }
        });
        panel.add(packageBtn, gbc);

        // 其他字段...
        // 模板名称
        gbc.gridx = 0;
        gbc.gridy = 2;
        panel.add(new JLabel(MessageUtil.getMessageSuffix("message.TemplateName")), gbc);
        gbc.gridx = 1;
        templateField = new JTextField(30);
        templateField.setText(state.templateName);
        panel.add(templateField, gbc);

        // 文件多选
        gbc.gridx = 0;
        gbc.gridy = 3;
        panel.add(new JLabel(MessageUtil.getMessageSuffix("message.FileSelection")), gbc);
        gbc.gridx = 1;
        gbc.gridwidth = 4;
        checkBoxPanel = new JPanel(new GridLayout(0, 3)); // 单列布局
        for (String file : GenTemplateAction.allFiles) {
            JCheckBox checkBox = new JCheckBox(file);
            if (state.files != null) {
                selectedFiles.clear();
                selectedFiles.addAll(state.files);
            }
            checkBox.setSelected(selectedFiles.contains(file));
            checkBox.addActionListener(e -> {
                if (checkBox.isSelected()) {
                    selectedFiles.add(file);
                } else {
                    selectedFiles.remove(file);
                }
            });
            checkBoxPanel.add(checkBox);
        }
        panel.add(checkBoxPanel, gbc);

        // 用户名
        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.gridwidth = 1;
        panel.add(new JLabel(MessageUtil.getMessageSuffix("message.Username")), gbc);
        gbc.gridx = 1;
        gbc.gridwidth = 2;
        userField = new JTextField(30);

        panel.add(userField, gbc);
        if (state.userName == null) {
            userField.setText(UserUtil.getCurrentUsername());
        } else {
            userField.setText(state.userName);
        }

        // 覆盖选项
        gbc.gridx = 0;
        gbc.gridy = 5;
        panel.add(new JLabel(MessageUtil.getMessageSuffix("message.Overwrite")), gbc);
        gbc.gridx = 1;
        gbc.gridwidth = 2;
        overwriteCheck = new JCheckBox();
        overwriteCheck.setSelected(Boolean.TRUE.equals(state.overWrite));
        panel.add(overwriteCheck, gbc);

        // 备注
        gbc.gridx = 0;
        gbc.gridy = 6;
        panel.add(new JLabel(MessageUtil.getMessageSuffix("message.Note")), gbc);
        gbc.gridx = 1;
        gbc.gridwidth = 2;
        noteArea = new JTextArea(5, 30);
        noteArea.setText(state.note);
        panel.add(new JScrollPane(noteArea), gbc);

        return panel;
    }

    @Override
    protected void doOKAction() {
        // 收集输入数据
        readInput();
        super.doOKAction();
    }

    @Override
    public void doCancelAction() {
        readInput();
        super.doCancelAction();
    }

    private void readInput() {
        state.projectDir = projectDirField.getText();
        state.savePkg = packageField.getText();
        state.templateName = templateField.getText();
        state.files = selectedFiles;
        state.userName = userField.getText();
        state.overWrite = overwriteCheck.isSelected();
        state.note = noteArea.getText();
    }

    @Override
    protected @Nullable ValidationInfo doValidate() {
        if (!FileUtil.exists(projectDirField.getText())) {
            return new ValidationInfo("Dir is not exist", projectDirField);
        }
        JTextComponent[] jComponent = new JTextComponent[]{projectDirField, packageField, templateField};
        for (JTextComponent component : jComponent) {
            if (StringUtils.isBlank(component.getText())) {
                return new ValidationInfo("Can't blank", component);
            }
        }
        // 检查包名：仅英文字符、数字、下划线、点
        if (!packageField.getText().matches("^[a-zA-Z0-9_.]+$") || packageField.getText().endsWith(".")) {
            return new ValidationInfo("Invalid package name", packageField);
        }
        if (selectedFiles.isEmpty()) {
            return new ValidationInfo("Please select at least one file", checkBoxPanel);
        }
        return super.doValidate();
    }

    public GenTemplateAction.GenTemplateState getInputData() {
        GenTemplateAction.GenTemplateState genTemplateState = new GenTemplateAction.GenTemplateState();
        XmlSerializerUtil.copyBean(state, genTemplateState);
        return genTemplateState;
    }
}
